#include <rte_ethdev.h>
#include <vector>

#pragma once

namespace kawauso {

    class EthernetDevice;

    /**
     * TODO
     */
    struct ReceiveQueue {
        EthernetDevice &device;
        uint16_t emptyRxPollCount = 0;
        uint16_t queueId;
    public:
        ReceiveQueue(uint16_t queueId, EthernetDevice &device, rte_mempool *packetBufferPool);
        [[nodiscard]] std::vector<rte_mbuf *> receivePackets() const;
    };

    /**
     * TODO
     */
    struct TransmitQueue {
        //
    };

    /**
     * TODO
     */
    class EthernetDevice {
        rte_eth_conf   portConfig;
        rte_eth_rxconf rxConfig;
        rte_eth_txconf txConfig;

        std::vector<ReceiveQueue *>  rxQueues;
        std::vector<TransmitQueue *> txQueues;

        std::string name;
        uint16_t rxDescNum;
        uint16_t txDescNum;
        uint16_t queueNum;
        uint16_t portId;
    public:
        EthernetDevice(uint16_t portId, uint16_t queueNum, rte_eth_dev_info &information);
        ~EthernetDevice();

        ReceiveQueue& getRxQueue(uint16_t queueId);
        [[nodiscard]] uint16_t getQueueCount() const;

        void init(std::vector<rte_mempool *> &packetBufferPools);

        friend class ReceiveQueue;
        friend class TransmitQueue;
    };

}